package com.today.usercenter;

import android.annotation.SuppressLint;
import android.content.Context;
import android.text.TextUtils;

import com.today.lib.common.account.Account;
import com.today.lib.common.account.UserInfo;
import com.today.lib.common.network.entity.EmptyResponseEntity;
import com.today.lib.common.ui.activity.WebViewActivity;
import com.today.lib.common.utils.ContextUtils;
import com.today.lib.common.utils.ToastUtils;
import com.today.usercenter.bus.events.TaskEvent;
import com.today.usercenter.network.RetrofitHelper;
import com.today.usercenter.network.entity.TaskInfoEntity;
import com.today.usercenter.network.entity.TaskResultEntity;
import com.today.usercenter.network.entity.TaskUserInfoEntity;

import org.greenrobot.eventbus.EventBus;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;

public class TaskManager {
    public static final int TASK_CLICK_AD = 1;
    public static final int TASK_SHARE_VIDEO = 2;
    public static final int TASK_WATCH_TV = 3;

    public interface ResultListener {
        void onCompleted(boolean success);
    }

    private static TaskManager instance;
    private TaskManager() {}
    public static TaskManager getInstance() {
        if (instance == null) {
            synchronized (TaskManager.class) {
                if (instance == null)
                    instance = new TaskManager();
            }
        }

        return instance;
    }

    private TaskInfoEntity mTaskInfo;

    public List<TaskInfoEntity.DataBean> getAll() {
        if (mTaskInfo == null)
            return null;

        return mTaskInfo.tasks;
    }

    public TaskInfoEntity.DataBean getTask(int id) {
        if (mTaskMap.isEmpty())
            return null;

        return mTaskMap.get(id);
    }

    public int getScore() {
        if (mTaskInfo == null)
            return 0;

        return mTaskInfo.totalpoints;
    }

    public Map<Integer, TaskInfoEntity.DataBean> mTaskMap = new HashMap<>();

    @SuppressLint("CheckResult")
    public void load(ResultListener listener) {
        if (mTaskInfo != null) {
            if (listener != null)
                listener.onCompleted(true);
            return;
        }

        RetrofitHelper.getTaskApi().getTaskInfo().subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(taskInfoEntity -> {
                    if (taskInfoEntity.busCode == EmptyResponseEntity.STATUS_OK) {
                        mTaskMap.clear();

                        for (TaskInfoEntity.DataBean task : taskInfoEntity.tasks) {
                            mTaskMap.put(task.id, task);
                        }

                        mTaskInfo = taskInfoEntity;
                    }

                    if (listener != null)
                        listener.onCompleted(taskInfoEntity.busCode == EmptyResponseEntity.STATUS_OK);
                }, throwable -> {
                    if (listener != null)
                        listener.onCompleted(false);
                    throwable.printStackTrace();
                });
    }

    public void showRulePage(Context context) {
        if (TextUtils.isEmpty(mTaskInfo.rule_url)) {
            return;
        }
        WebViewActivity.launch(context, mTaskInfo.rule_url);
    }

    private void updateScore(int id, TaskResultEntity result) {
        if (mTaskInfo != null) {
            mTaskInfo.totalpoints = result.totalpoints;

            TaskInfoEntity.DataBean bean = mTaskMap.get(id);
            if (bean != null) {
                bean.count++;
            }

            EventBus.getDefault().post(new TaskEvent());
        }
    }

    public void gain(int type) {
        gain(type, null);
    }

    @SuppressLint("CheckResult")
    public void gain(int type, ResultListener listener) {
        TaskInfoEntity.DataBean bean = TaskManager.getInstance().getTask(type);
        if (bean == null)
            return;

        if (bean.count >= bean.threshold)
            return;

        RetrofitHelper.getTaskApi().gainScore(type).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(taskResultEntity -> {
                    if (taskResultEntity.busCode == EmptyResponseEntity.STATUS_OK) {
                        if (taskResultEntity.task_scores > 0) {
                            updateScore(type, taskResultEntity);
                            ToastUtils.showToast(String.format(ContextUtils.getContext().getString(R.string.task_result_format), taskResultEntity.task_scores, taskResultEntity.totalpoints));
                            if (listener != null)
                                listener.onCompleted(true);
                        }
                    } else if (!TextUtils.isEmpty(taskResultEntity.busMsg)) {
                        ToastUtils.showToast(taskResultEntity.busMsg);
                    }

                }, throwable -> {
                    throwable.printStackTrace();
                });
    }

    @SuppressLint("CheckResult")
    public boolean consume(int points, ResultListener listener) {
        if (!isEnough(points))
            return false;

        RetrofitHelper.getTaskApi().consumeScore(points).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(consumeResultEntity -> {
                    if (consumeResultEntity.busCode == EmptyResponseEntity.STATUS_OK) {
                        if (mTaskInfo != null) {
                            mTaskInfo.totalpoints -= points;
                            EventBus.getDefault().post(new TaskEvent());
                        }
                    } else if (!TextUtils.isEmpty(consumeResultEntity.busMsg)) {
                        ToastUtils.showToast(consumeResultEntity.busMsg);
                    }

                    if (listener != null)
                        listener.onCompleted(consumeResultEntity.busCode == EmptyResponseEntity.STATUS_OK);
                }, throwable -> {
                    if (listener != null)
                        listener.onCompleted(false);

                    throwable.printStackTrace();
                });

        return true;
    }

    public boolean isEnough(int need) {
        return mTaskInfo != null && mTaskInfo.totalpoints >= need;
    }
}
